﻿using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Console = Colorful.Console;

namespace nnp7ChatDemo
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            Console.CancelKeyPress += Console_CancelKeyPress;

            var prg = new Program();
            _ = prg.selectRunMode();

            //等待结束          
            while (!consoleCancel.IsCancellationRequested)
            {
                try
                {
                    await Task.Delay(1000, consoleCancel.Token);
                }
                catch { }
            }
            ShowSysInfo("程序结束");
        }

        private static void Console_CancelKeyPress(object? sender, ConsoleCancelEventArgs e)
        {
            consoleCancel.Cancel();
            Environment.Exit(0);
        }
        static CancellationTokenSource consoleCancel = new();



        private async Task selectRunMode()
        {
            while (true)
            {
                ShowSysInfo($"nnp7 demo");
                ShowSysInfo($"选择运行模式\r\n\t[1]服务端模式\r\n\t[2]客户端模式");
                switch (Console.ReadKey().Key)
                {
                    case ConsoleKey.D1:
                        await toServerMode();
                        return;

                    case ConsoleKey.D2:
                        await toClientMode();
                        return;

                    default:
                        continue;
                }
            }
        }



        string host = "127.0.0.1";
        int port = 59394;

        /// <summary>
        /// 聊天通讯协议
        /// </summary>
        ChatProtocol ChatProto;




        #region 客户端模式

        private async Task toClientMode()
        {
            try
            {
                TcpClient client = new();
                ShowSysInfo($"\r\n开始连接{host}:{port}..");
                await client.ConnectAsync(IPAddress.Parse(host), port);
                ShowSysInfo($"已连接.");

                //连接后构造通讯协议
                ChatProto = new(client);     //构成时若数据包处理方法不正确会抛出异常
                await toChatMode();
            }
            catch (Exception ex)
            {
                ShowSysInfo(ex.Message);
            }
        }



        #endregion




        #region 服务端模式

        private async Task toServerMode()
        {
            try
            {
                listener = new(new IPEndPoint(IPAddress.Any, port));
                listener.Start();
                ShowSysInfo($"\r\n监听端口{port}..");

                TcpClient client = await listener.AcceptTcpClientAsync();
                ShowSysInfo($"新连接");

                //连接后构造通讯协议
                ChatProto = new(client);        //构成时若数据包处理方法不正确会抛出异常
                await toChatMode();
            }
            catch (Exception ex)
            {
                ShowSysInfo(ex.Message);
            }
        }
        TcpListener listener;

        #endregion



        #region 聊天模式

        private async Task toChatMode()
        {
            //设置名字
            while (true)
            {
                ShowSysInfo("您的聊天名字:");
                string? name = readLine();
                if (string.IsNullOrEmpty(name)) continue;
                else
                {
                    ChatProto.Name = name;
                    break;
                }
            }

            //聊天
            while (true)
            {
                try
                {
                    //发送表情是为了单独测试“表情数据包”
                    ShowSysInfo($"输入要发送的信息(单独发送表情\\u1:\U0001F600 \\u2:\u2764\uFE0F):");
                    string? line = readLine();
                    if (string.IsNullOrEmpty(line)) continue;

                    if (line == "exit")
                    {
                        consoleCancel.Cancel();
                        return;
                    }

                    switch (line)
                    {

                        //发送表情
                        case "\\u1":
                            await ChatProto.Emoji(EmojiPkg.EmojiType.笑脸);
                            break;

                        case "\\u2":
                            await ChatProto.Emoji(EmojiPkg.EmojiType.红心);
                            break;

                        default:
                            //发送文字聊天内容
                            await ChatProto.Chat(line);
                            break;
                    }
                }
                catch (Exception e)
                {
                    ShowSysInfo(e.Message);
                    break;
                }
            }
        }

        string? readLine()
        {
            return System.Console.ReadLine()?.Trim();
        }

        #endregion



        #region 控制台输出


        public static void ShowSysInfo(string msg) => Console.WriteLine(msg, Color.Yellow);

        public static void ShowRecvInfo(string msg) => Console.WriteLine(msg, Color.LightGreen);

        public static void ShowSendInfo(string msg) => Console.WriteLine(msg, Color.LightPink);

        #endregion




    }

}
